home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dc1 / rules.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  26KB  |  1,040 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  RULES.C
  9.  *
  10.  *  Note that certain operations are available for store-down optimization.
  11.  *  That is, char a, b; a = ~b; ... we can do the invert operation on a byte.
  12.  *  These operators are:    and,or,xor,invert,add,sub
  13.  *
  14.  *  Note: void detection rules should only apply for TID_INT types since
  15.  *  external arrays[] will have size 0
  16.  *
  17.  *  only code gen routines associated with data movement need
  18.  *  understand bit field storage types and only GenCast() &
  19.  *  assignment exp tree routines.
  20.  */
  21.  
  22. #include "defs.h"
  23.  
  24. Prototype   void BinaryRules(Exp *);
  25. Prototype   void BinaryArithRules(Exp *);
  26. Prototype   void BinaryLogicRules(Exp *);
  27. Prototype   void UnaryLogicRules(Exp *);
  28. Prototype   void UnaryRules(Exp *);
  29. Prototype   void UnaryArithRules(Exp *);
  30. Prototype   void ShiftRules(Exp *);
  31. Prototype   void AddRules(Exp *);
  32. Prototype   void SubRules(Exp *);
  33. Prototype   void FloatingRules(Exp *);
  34. Prototype   void AssignRules(Exp *);
  35. Prototype   void InitRules(Exp **, Type *);
  36. Prototype   void CompareRules(Exp *, int);
  37. Prototype   void MatchRules(Exp *);
  38. Prototype   void OptBinaryArithRules(Exp *);
  39. Prototype   void OptBinaryRules(Exp *);
  40.  
  41. Prototype   int  CheckConversion(Exp *, Type *, Type *);
  42.  
  43. Prototype   int  CreateBinaryResultStorage(Exp *, short);
  44. Prototype   int  CreateUnaryResultStorage(Exp *, short);
  45.  
  46. Local        int  CastIfConstantFit(Exp **, Type *);
  47. Prototype   short   AutoResultStorage(Exp *);
  48.  
  49. /*
  50.  *  Standard Binary Rules
  51.  */
  52.  
  53. void
  54. BinaryRules(exp)
  55. Exp *exp;
  56. {
  57.     Type *t1;
  58.     Type *t2;
  59.     short doUnsigned;
  60.  
  61.     if (exp->ex_Flags & EF_ASSEQ)
  62.     return(AssignRules(exp));
  63.  
  64.     t1 = exp->ex_ExpL->ex_Type;
  65.     t2 = exp->ex_ExpR->ex_Type;
  66.     doUnsigned = 0;
  67.  
  68.     Assert(t1);
  69.     Assert(t2);
  70.  
  71.     if (t1->Id != TID_INT || t2->Id != TID_INT) {
  72.     yerror(exp->ex_LexIdx, EERROR_EXPECTED_INT_TYPE);
  73.     exp->ex_Type = &LongType;
  74.     return;
  75.     }
  76.     if ((t1->Size==0 && t1->Id==TID_INT) || (t2->Size==0 && t2->Id==TID_INT)) {
  77.     yerror(exp->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  78.     exp->ex_Type = &LongType;
  79.     return;
  80.     }
  81.  
  82.  
  83.     if (t1->Id == TID_INT && (t1->Flags & TF_UNSIGNED))
  84.     doUnsigned = 1;
  85.     if (t2->Id == TID_INT && (t2->Flags & TF_UNSIGNED))
  86.     doUnsigned = 1;
  87.  
  88.     if (t1->Id == TID_INT && (t1->Size < INT_SIZE || (doUnsigned && (t1->Flags & TF_UNSIGNED) == 0))) {
  89.     if (doUnsigned)
  90.         InsertCast(&exp->ex_ExpL, &ULongType);
  91.     else
  92.         InsertCast(&exp->ex_ExpL, &LongType);
  93.     }
  94.     if (t2->Id == TID_INT && (t2->Size < INT_SIZE || (doUnsigned && (t2->Flags & TF_UNSIGNED) == 0))) {
  95.     if (doUnsigned)
  96.         InsertCast(&exp->ex_ExpR, &ULongType);
  97.     else
  98.         InsertCast(&exp->ex_ExpR, &LongType);
  99.     }
  100.     if (doUnsigned)
  101.     exp->ex_Type = &ULongType;
  102.     else
  103.     exp->ex_Type = &LongType;
  104. }
  105.  
  106. void
  107. BinaryArithRules(exp)
  108. Exp *exp;
  109. {
  110.     if (exp->ex_ExpL->ex_Type->Id == TID_FLT || exp->ex_ExpR->ex_Type->Id == TID_FLT) {
  111.     FloatingRules(exp);
  112.     return;
  113.     }
  114.     BinaryRules(exp);
  115. }
  116.  
  117.  
  118. /*
  119.  *  Optimized Binary Arithmatic Rules.    This allows the two source
  120.  *  operands to be of smaller types than the destination.  For
  121.  *  example, in genarith.c/GenStar() (multiply), so the MULS/MULU
  122.  *  instruction may be optimized in.
  123.  *
  124.  *  Note that in this case the result type is allowed to be either
  125.  *  a short or a long, but not a char.    This compromise makes code
  126.  *  generation easier.
  127.  */
  128.  
  129. void
  130. OptBinaryRules(exp)
  131. Exp *exp;
  132. {
  133.     Type *t1;
  134.     Type *t2;
  135.     Type *t;
  136.     short doUnsigned;
  137.     short size;
  138.  
  139.     if (exp->ex_Flags & EF_ASSEQ)
  140.     return(AssignRules(exp));
  141.  
  142.     t1 = exp->ex_ExpL->ex_Type;
  143.     t2 = exp->ex_ExpR->ex_Type;
  144.     doUnsigned = 0;
  145.  
  146.     Assert(t1);
  147.     Assert(t2);
  148.  
  149.     if (t1->Id != TID_INT || t2->Id != TID_INT) {
  150.     yerror(exp->ex_LexIdx, EERROR_EXPECTED_INT_TYPE);
  151.     exp->ex_Type = &LongType;
  152.     return;
  153.     }
  154.     if (t1->Size == 0 || t2->Size == 0) {
  155.     yerror(exp->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  156.     exp->ex_Type = &LongType;
  157.     return;
  158.     }
  159.  
  160.     if (t1->Flags & TF_UNSIGNED)
  161.     doUnsigned = 1;
  162.     if (t2->Flags & TF_UNSIGNED)
  163.     doUnsigned = 1;
  164.  
  165.     size = 2;
  166.     if (t1->Size > size)
  167.     size = t1->Size;
  168.     if (t2->Size > size)
  169.     size = t2->Size;
  170.  
  171.     if (doUnsigned) {
  172.     if (size == 2)
  173.         t = &UShortType;
  174.     else
  175.         t = &ULongType;
  176.     } else {
  177.     if (size == 2)
  178.         t = &ShortType;
  179.     else
  180.         t = &LongType;
  181.     }
  182.     if (t1 != t)
  183.     InsertCast(&exp->ex_ExpL, t);
  184.     if (t2 != t)
  185.     InsertCast(&exp->ex_ExpR, t);
  186.  
  187.     if (exp->ex_Type && exp->ex_Type->Id == TID_INT) {
  188.     if (exp->ex_Type->Size == 1)
  189.         exp->ex_Type = (doUnsigned) ? &UShortType : &ShortType;
  190.     } else {
  191.     exp->ex_Type = (doUnsigned) ? &ULongType : &LongType;
  192.     }
  193. }
  194.  
  195. void
  196. OptBinaryArithRules(exp)
  197. Exp *exp;
  198. {
  199.     if (exp->ex_ExpL->ex_Type->Id == TID_FLT || exp->ex_ExpR->ex_Type->Id == TID_FLT) {
  200.     FloatingRules(exp);
  201.     return;
  202.     }
  203.     OptBinaryRules(exp);
  204. }
  205.  
  206. /*
  207.  *  For logic operations.  If the result type is known we
  208.  *  optimize to the largest type of the three (two args and
  209.  *  result type).
  210.  */
  211.  
  212. void
  213. BinaryLogicRules(exp)
  214. Exp *exp;
  215. {
  216.     Exp *e1;
  217.     Exp *e2;
  218.     Type *type;
  219.  
  220.     if ((type = exp->ex_Type) == NULL || type->Id != TID_INT) {
  221.     BinaryRules(exp);
  222.     return;
  223.     }
  224.  
  225.     /*
  226.      *    Extend or truncate to the return type since all other bits will be
  227.      *    ignored (and for logic operations we can cut it off like this no prob)
  228.      */
  229.  
  230.     e1 = exp->ex_ExpL;
  231.     e2 = exp->ex_ExpR;
  232.  
  233.     if (e1->ex_Type->Id == TID_FLT || e2->ex_Type->Id == TID_FLT) {
  234.     yerror(exp->ex_LexIdx, EERROR_EXPECTED_INT_TYPE);
  235.     }
  236.  
  237.     if (e1->ex_Type != type)
  238.     InsertCast(&exp->ex_ExpL, type);
  239.     if (e2->ex_Type != type)
  240.     InsertCast(&exp->ex_ExpR, type);
  241. }
  242.  
  243. /*
  244.  *  The result is the type of the argument or the type the parent expects,
  245.  *  whichever is larger.  Example (byte).  If parent expects byte we do not
  246.  *  need to cast to <partype>,    but if it does not we MUST cast to the parent's
  247.  *  type.
  248.  *
  249.  *    [00]80 ^ -1 (byte) -> [FF]7F
  250.  */
  251.  
  252. void
  253. UnaryLogicRules(exp)
  254. Exp *exp;
  255. {
  256.     Exp *e1;
  257.     Type *type = exp->ex_Type;
  258.     Type *t1;
  259.  
  260.     if (type == NULL || type->Id != TID_INT) {
  261.     UnaryRules(exp);
  262.     return;
  263.     }
  264.     e1 = exp->ex_ExpL;
  265.     t1 = e1->ex_Type;
  266.  
  267.     if (type->Size == 0) {
  268.     yerror(e1->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  269.     type = &LongType;
  270.     }
  271.     if (t1->Id == TID_FLT) {
  272.     yerror(e1->ex_LexIdx, EERROR_EXPECTED_INT_TYPE);
  273.     type = &LongType;
  274.     }
  275.  
  276.     if (type != t1)
  277.     InsertCast(&exp->ex_ExpL, type);
  278. }
  279.  
  280. void
  281. UnaryRules(exp)
  282. Exp *exp;
  283. {
  284.     Type *t;
  285.     short doUnsigned;
  286.  
  287.     t = exp->ex_ExpL->ex_Type;
  288.     doUnsigned = 0;
  289.  
  290.     Assert(t);
  291.  
  292.     if (t->Id == TID_INT && (t->Flags & TF_UNSIGNED))
  293.     doUnsigned = 1;
  294.  
  295.     if (t->Id == TID_INT && t->Size < INT_SIZE) {
  296.     if (t->Size == 0)
  297.         yerror(exp->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  298.     if (doUnsigned)
  299.         InsertCast(&exp->ex_ExpL, &ULongType);
  300.     else
  301.         InsertCast(&exp->ex_ExpL, &LongType);
  302.     }
  303.     if (doUnsigned)
  304.     exp->ex_Type = &ULongType;
  305.     else
  306.     exp->ex_Type = &LongType;
  307. }
  308.  
  309. void
  310. UnaryArithRules(exp)
  311. Exp *exp;
  312. {
  313.     Exp *e1 = exp->ex_ExpL;
  314.  
  315.     if (e1->ex_Type->Id == TID_FLT) {
  316.     exp->ex_Type = e1->ex_Type;
  317.     return;
  318.     }
  319.     UnaryRules(exp);
  320. }
  321.  
  322. void
  323. ShiftRules(exp)
  324. Exp *exp;
  325. {
  326.     Exp *e1 = exp->ex_ExpL;
  327.     Exp *e2 = exp->ex_ExpR;
  328.     Type *t1 = e1->ex_Type;
  329.     Type *t2 = e2->ex_Type;
  330.  
  331.     Assert(t1);
  332.     Assert(t2);
  333.  
  334.     if (exp->ex_Flags & EF_ASSEQ) {
  335.     exp->ex_Type = t1;
  336.     return;
  337.     }
  338.  
  339.     if (t1->Size != 4) {
  340.         if (t1->Size == 0)
  341.         yerror(e1->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  342.     if (t1->Flags & TF_UNSIGNED)
  343.         InsertCast(&exp->ex_ExpL, &ULongType);
  344.     else
  345.         InsertCast(&exp->ex_ExpL, &LongType);
  346.     }
  347.     exp->ex_Type = exp->ex_ExpL->ex_Type;
  348. }
  349.  
  350. /*
  351.  *  AddRules(exp)
  352.  *
  353.  *  Basically handle the special case of (ary/ptr + int) and (int + ary/ptr)
  354.  *  Note that in this case the size of the 'int' is not cast.
  355.  */
  356.  
  357. void
  358. AddRules(exp)
  359. Exp *exp;
  360. {
  361.     Type *t1 = exp->ex_ExpL->ex_Type;
  362.     Type *t2 = exp->ex_ExpR->ex_Type;
  363.  
  364.     Assert(t1);
  365.     Assert(t2);
  366.     exp->ex_Token = 0;
  367.  
  368.     if ((t1->Id == TID_PTR || t1->Id == TID_ARY) && t2->Id == TID_INT) {
  369.         if (t1->SubType->Size == 0 && t1->SubType->Id == TID_INT)
  370.         yerror(exp->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  371.         if (t2->Size == 0)
  372.         yerror(exp->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  373.         exp->ex_Token = 1;
  374.     exp->ex_Type = t1;
  375.     /* xxx if autoassign insert type */
  376.     } else if (t1->Id == TID_INT && (t2->Id == TID_PTR || t2->Id == TID_ARY)) {
  377.     Exp *etmp = exp->ex_ExpL;
  378.  
  379.         if (t1->Size == 0)
  380.         yerror(exp->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  381.         if (t2->SubType->Size == 0 && t2->SubType->Id == TID_INT)
  382.         yerror(exp->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  383.  
  384.     exp->ex_ExpL = exp->ex_ExpR;
  385.     exp->ex_ExpR = etmp;
  386.     exp->ex_Type = t2;
  387.     exp->ex_Token = 1;
  388.     if (exp->ex_Flags & EF_ASSEQ)
  389.         yerror(exp->ex_LexIdx, EERROR_ILLEGAL_PTR_ARITH);
  390.     /* xxx if autoassign insert type */
  391.     } else {
  392.         if (t1->Size == 0)
  393.         yerror(exp->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  394.         if (t2->Size == 0)
  395.         yerror(exp->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  396.  
  397.     if (exp->ex_Type && exp->ex_Type->Id == TID_INT && t1->Id == TID_INT && t2->Id == TID_INT) {
  398.         if (exp->ex_Type != t1)
  399.         InsertCast(&exp->ex_ExpL, exp->ex_Type);
  400.         if (exp->ex_Type != t2)
  401.         InsertCast(&exp->ex_ExpR, exp->ex_Type);
  402.     } else {
  403.         BinaryArithRules(exp);
  404.     }
  405.     }
  406. }
  407.  
  408. /*
  409.  *  SubRules()    Basically handle ptr - ptr and let other routines
  410.  *        worry about other combinations.
  411.  */
  412.  
  413. void
  414. SubRules(exp)
  415. Exp *exp;
  416. {
  417.     Type *t1 = exp->ex_ExpL->ex_Type;
  418.     Type *t2 = exp->ex_ExpR->ex_Type;
  419.  
  420.     if (t1->Id == TID_ARY) {
  421.     InsertCast(&exp->ex_ExpL, TypeToPtrType(t1->SubType));
  422.     t1 = exp->ex_ExpL->ex_Type;
  423.     }
  424.     if (t2->Id == TID_ARY) {
  425.     InsertCast(&exp->ex_ExpR, TypeToPtrType(t2->SubType));
  426.     t2 = exp->ex_ExpR->ex_Type;
  427.     }
  428.     if (t1->Id == TID_PTR && t2->Id == TID_PTR) {
  429.     exp->ex_Token = 2;
  430.     exp->ex_Type = &LongType;
  431.     } else {
  432.     if (t2->Id == TID_PTR)
  433.         yerror(exp->ex_ExpR->ex_LexIdx, EERROR_ILLEGAL_PTR_ARITH);
  434.     AddRules(exp);
  435.     }
  436. }
  437.  
  438. /*
  439.  *  floating rules (binary).  One or both sides are FP, cast to the largest
  440.  *  of the two, except if EF_ASSEQ cast to lhs.
  441.  */
  442.  
  443. void
  444. FloatingRules(exp)
  445. Exp *exp;
  446. {
  447.     Type *t1 = exp->ex_ExpL->ex_Type;
  448.     Type *t2 = exp->ex_ExpR->ex_Type;
  449.  
  450. #ifdef REGISTERED
  451.     if (exp->ex_Flags & EF_ASSEQ) {
  452.     if (t1 != t2)
  453.         InsertCast(&exp->ex_ExpR, t1);
  454.     exp->ex_Type = t1;
  455.     return;
  456.     }
  457.     if (t1->Id == TID_FLT && t2->Id == TID_FLT) {
  458.     if (t1->Size > t2->Size)
  459.         InsertCast(&exp->ex_ExpR, t1);
  460.     else if (t2->Size > t1->Size) {
  461.         InsertCast(&exp->ex_ExpL, t2);
  462.         t1 = t2;
  463.     }
  464.     } else if (t1->Id == TID_FLT) {
  465.     InsertCast(&exp->ex_ExpR, t1);
  466.     } else {
  467.     InsertCast(&exp->ex_ExpL, t2);
  468.     t1 = t2;
  469.     }
  470.     exp->ex_Type = t1;
  471. #else
  472.     yerror(exp->ex_LexIdx, EUNREG_FLOATINGPT);
  473. #endif
  474. }
  475.  
  476. /*
  477.  *  cast the right side to the left side's type
  478.  *
  479.  *  exception:    if left side is a bitfield right side is cast to a long
  480.  *        if right side is a bitfield it is cast to a long
  481.  *
  482.  *        assign takes this into account
  483.  */
  484.  
  485. void
  486. AssignRules(exp)
  487. Exp *exp;
  488. {
  489.     Assert(exp->ex_ExpL);
  490.     Assert(exp->ex_ExpR);
  491.  
  492.     InitRules(&exp->ex_ExpR, exp->ex_ExpL->ex_Type);
  493.  
  494.     /*
  495.      * Old code: returned the right hand type.
  496.      *
  497.      * New code: returns the left hand type if a bitfield, else the righthand
  498.      * type.
  499.      *
  500.      * Properly, this code should always return the LEFT hand type.  It
  501.      * turns out that the right hand and left hand types are the same in all
  502.      * cases except for bitfields.  at least, they are supposed to be... I'm
  503.      * not 100% sure, so for release 13 I am fixing it to return the left 
  504.      * hand type JUST for bitfields, so as not to break something that is
  505.      * known to work.
  506.      */
  507.  
  508.     if (exp->ex_ExpL->ex_Type->Id == TID_BITFIELD)
  509.     exp->ex_Type = exp->ex_ExpL->ex_Type;
  510.     else
  511.     exp->ex_Type = exp->ex_ExpR->ex_Type;
  512. }
  513.  
  514. /*
  515.  *  cast the right side to the left side's type
  516.  *
  517.  *  exception:    if left side is a bitfield right side is cast to a long
  518.  *        if right side is a bitfield it is cast to a long
  519.  *
  520.  *        assign takes this into account
  521.  */
  522.  
  523. void
  524. InitRules(pexp, t1)
  525. Exp **pexp;
  526. Type *t1;
  527. {
  528.     Exp *exp = *pexp;
  529.     Type *t2;
  530.     int errorcode = EERROR_ILLEGAL_ASSIGNMENT;
  531.  
  532.     t2 = exp->ex_Type;
  533.  
  534.     Assert(t1);
  535.     Assert(t2);
  536.  
  537.     if ((t1->Size == 0) ||
  538.         (t2->Size == 0 && t2->Id == TID_INT))
  539.     {
  540.     errorcode = EERROR_UNEXPECTED_VOID_TYPE;
  541.     }
  542.  
  543.     else if (t1->Id == TID_BITFIELD)
  544.     {
  545.         if (t1->Flags & TF_UNSIGNED)
  546.         t1 = &ULongType;
  547.     else
  548.         t1 = &LongType;
  549.     if (t2->Id != TID_INT)
  550.         yerror(exp->ex_LexIdx, EERROR_ILLEGAL_BITFIELD_OP);
  551.     InsertCast(pexp, t1);
  552.  
  553.         /*
  554.          * XXX ifdef'd out code entirely ... totally broken XXX
  555.          *
  556.          * First of all, it is overriding ex_Type for the RHS which
  557.          * screws up storage access to the rhs.  Secondly, it cannot 
  558.          * deal with a bitfield in the rhs.
  559.          */
  560. #ifdef NOTDEF
  561.     if (t1->Flags & TF_UNSIGNED)
  562.         t1 = &ULongType;
  563.     else
  564.         t1 = &LongType;
  565.     if (t2->Id != TID_INT)
  566.         yerror(exp->ex_LexIdx, EERROR_ILLEGAL_BITFIELD_OP);
  567.  
  568.     /*
  569.      *  do not insert cast as this is the lhs.  GENASS.C handles assignment
  570.      *  by not attempting to thrust lhs storage into rhs's return storage.
  571.      */
  572.  
  573.     exp->ex_Type = t1;
  574. #endif
  575.     return;
  576.     }
  577.  
  578.     /* exp->ex_Type = t1; */
  579.  
  580.  
  581.     /*
  582.      *    Convert array of x to pointer to x
  583.      */
  584.  
  585.     if (t2->Id == TID_ARY)
  586.     {
  587.     InsertCast(pexp, t2 = TypeToPtrType(t2->SubType));
  588.     }
  589.  
  590.     if (t1->Id == t2->Id)
  591.     {
  592.         errorcode = 0;
  593.  
  594.         /* If they are both pointers, make sure that they point to the same */
  595.         /* thing before issuing a warning.                                  */
  596.         if (t1->Id == TID_PTR)
  597.         {
  598.        CheckPointerType(exp->ex_LexIdx, exp->ex_LexIdx, t1, t2);
  599.     }
  600.         /* Not pointers, but we should check to see that the objects are the */
  601.         /* same size (since they are the same type).  This check currently   */
  602.         /* lets through structures which are the same size, but since we     */
  603.         /* are not expecting them here we can ignore it for now???           */
  604.     else if (t1->Size != t2->Size)
  605.     {
  606.         if (t1->Id != TID_INT && t1->Id != TID_FLT)
  607.            errorcode = EERROR_ILLEGAL_ASSIGNMENT;
  608.     }
  609.     }
  610.  
  611.     /* * * * * * * * * * * * * * * * * * * * * * * * * * * */
  612.     /*                                                     */
  613.     /* Check for conversions from a pointer to an integer  */
  614.     /*                                                     */
  615.     /* * * * * * * * * * * * * * * * * * * * * * * * * * * */
  616.     else if (t1->Id == TID_PTR && t2->Id == TID_INT)
  617.     {
  618.         errorcode = EWARN_INT_PTR_CONVERSION;
  619.  
  620.         /* If we are converting from a constant integer to a pointer, */
  621.         /* we can let them get away with converting a constant NULL   */
  622.     if (exp->ex_Stor.st_Type == ST_IntConst)
  623.     {
  624.         /* Supress the error message when they are casting a constant NULL */
  625.         if (exp->ex_Stor.st_IntConst == 0)
  626.            errorcode = 0;
  627.     }
  628.     else
  629.     {
  630.         /* We need to tell them that converting from an integer to a */
  631.         /* pointer is a bad thing.  We do want to give them a more   */
  632.         /* meaningful message when they are doing something that is  */
  633.         /* of a different size.                                      */
  634.         if (t1->Size != t2->Size)
  635.            errorcode = EERROR_ILLEGAL_PTR_INT_SIZE;
  636.     }
  637.     }
  638.  
  639.     /* * * * * * * * * * * * * * * * * * * * * * * * * * * */
  640.     /*                                                     */
  641.     /* Check for conversions from an integer to a pointer  */
  642.     /*                                                     */
  643.     /* * * * * * * * * * * * * * * * * * * * * * * * * * * */
  644.     else if (t1->Id == TID_INT && t2->Id == TID_PTR)
  645.     {
  646.     if (t1->Size != t2->Size)
  647.         errorcode = EERROR_ILLEGAL_PTR_INT_SIZE;
  648.     }
  649.  
  650.     /* * * * * * * * * * * * * * * * * * * * * * * * * * * */
  651.     /*                                                     */
  652.     /* Check for conversions between floats and integers   */
  653.     /*                                                     */
  654.     /* * * * * * * * * * * * * * * * * * * * * * * * * * * */
  655.     else if ((t1->Id == TID_INT && t2->Id == TID_FLT) ||
  656.         (t1->Id == TID_FLT && t2->Id == TID_INT))
  657.     {
  658.         /* This type of conversion is really considered silent */
  659.         errorcode = 0;
  660.     }
  661.  
  662.     /* * * * * * * * * * * * * * * * * * * * * * * * * * * */
  663.     /*                                                     */
  664.     /* When we get here, we have run out of cases to check */
  665.     /* We must therefore assume that what they are doing   */
  666.     /* is illegal and give them an error message           */
  667.     /*                                                     */
  668.     /* * * * * * * * * * * * * * * * * * * * * * * * * * * */
  669.  
  670.     if (errorcode)
  671.        yerror(exp->ex_LexIdx, errorcode);
  672.     InsertCast(pexp, t1);
  673. }
  674.  
  675.  
  676.  
  677. /*
  678.  *  CompareRules(exp)
  679.  *
  680.  *    If either side is a bit field it is cast into a long/ulong.
  681.  *
  682.  *    Whichever side is the largest type, the other side is promoted.  For
  683.  *    example, if one side is a short and the other a byte then the
  684.  *    byte is promoted to a short.
  685.  *
  686.  *    If either side is unsigned or a pointer then both sides are promoted
  687.  *    to unsigned.
  688.  *
  689.  *    If one side is an integer constant and the other side is an
  690.  *    integer quantity attempt to fit the integer constant into
  691.  *    the size of the int.
  692.  *
  693.  *    If either side is fp convert both sides to whichever is largest
  694.  */
  695.  
  696. void
  697. CompareRules(exp, bigok)
  698. Exp *exp;
  699. int bigok;
  700. {
  701.     Type *t1 = exp->ex_ExpL->ex_Type;
  702.     Type *t2 = exp->ex_ExpR->ex_Type;
  703.     short doUnsigned = 0;
  704.     short size;
  705.     Type *type = &VoidType;
  706.  
  707.     Assert(t1);
  708.     Assert(t2);
  709.  
  710.     if (exp->ex_Flags & EF_ASSEQ)
  711.     Assert(0);
  712.     exp->ex_Type = &LongType;
  713.  
  714.     if (t1->Id == TID_STRUCT || t1->Id == TID_UNION || t2->Id == TID_STRUCT || t2->Id == TID_UNION) {
  715.     if (!bigok)
  716.         yerror(exp->ex_LexIdx, EERROR_ILLEGAL_STRUCT_OP);
  717.     else if (t1->Size != t2->Size)
  718.         yerror(exp->ex_LexIdx, EERROR_ILLEGAL_STRUCT_OP);
  719.     return;
  720.     }
  721.  
  722.     if (t1->Id == TID_FLT || t2->Id == TID_FLT) {
  723.     FloatingRules(exp);        /*  messes up ex_Type    */
  724.     exp->ex_Type = &LongType;
  725.     return;
  726.     }
  727.  
  728.     if (t1->Size != t2->Size) {
  729.     if (exp->ex_ExpL->ex_Stor.st_Type == ST_IntConst && t2->Id == TID_INT) {
  730.         if (CastIfConstantFit(&exp->ex_ExpL, t2))
  731.         return;
  732.     }
  733.     if (exp->ex_ExpR->ex_Stor.st_Type == ST_IntConst && t1->Id == TID_INT) {
  734.         if (CastIfConstantFit(&exp->ex_ExpR, t1))
  735.         return;
  736.     }
  737.     }
  738.  
  739.     if (t1->Id == TID_INT && (t1->Flags & TF_UNSIGNED))
  740.     doUnsigned = 1;
  741.     if (t2->Id == TID_INT && (t2->Flags & TF_UNSIGNED))
  742.     doUnsigned = 1;
  743.  
  744.     size = (t1->Size > t2->Size) ? t1->Size : t2->Size;
  745.  
  746.     if (t1->Id == TID_ARY)
  747.     InsertCast(&exp->ex_ExpL, t1 = TypeToPtrType(t1->SubType));
  748.     if (t2->Id == TID_ARY)
  749.     InsertCast(&exp->ex_ExpR, t2 = TypeToPtrType(t2->SubType));
  750.  
  751.     if (t1->Size == 0)
  752.     yerror(exp->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  753.     if (t2->Size == 0)
  754.     yerror(exp->ex_LexIdx, EERROR_UNEXPECTED_VOID_TYPE);
  755.  
  756.     if (t1->Id == TID_PTR && t2->Id == TID_PTR) {
  757.     CheckPointerType(exp->ex_LexIdx, exp->ex_LexIdx, t1, t2);
  758.     return;
  759.     } else if (t1->Id == TID_PTR || t2->Id == TID_PTR) {
  760.     if (t1->Id == TID_INT) {
  761.         Exp *e1 = exp->ex_ExpL;
  762.         if (e1->ex_Stor.st_Type != ST_IntConst || e1->ex_Stor.st_IntConst != 0)
  763.         yerror(e1->ex_LexIdx, EWARN_PTR_INT_MISMATCH);
  764.         type = t2;
  765.     }
  766.     if (t2->Id == TID_INT) {
  767.         Exp *e2 = exp->ex_ExpR;
  768.         if (e2->ex_Stor.st_Type != ST_IntConst || e2->ex_Stor.st_IntConst != 0)
  769.         yerror(e2->ex_LexIdx, EWARN_PTR_INT_MISMATCH);
  770.         type = t1;
  771.     }
  772.     doUnsigned = 1;
  773.     } else {
  774.     switch(size) {
  775.     case 1:
  776.         type = (doUnsigned) ? &UCharType : &CharType;
  777.         break;
  778.     case 2:
  779.         type = (doUnsigned) ? &UShortType : &ShortType;
  780.         break;
  781.     case 4:
  782.         type = (doUnsigned) ? &ULongType : &LongType;
  783.         break;
  784.     default:
  785.         yerror(exp->ex_LexIdx, ESOFT_ILLEGAL_COMPARE);
  786.         break;
  787.     }
  788.     }
  789.     InsertCast(&exp->ex_ExpL, type);
  790.     InsertCast(&exp->ex_ExpR, type);
  791. }
  792.  
  793. /*
  794.  *  Compare rules but result is the combined type, not an integer.
  795.  *  ( question-colon operator )
  796.  */
  797.  
  798. void
  799. MatchRules(exp)
  800. Exp *exp;
  801. {
  802.     Type *t1 = exp->ex_ExpL->ex_Type;
  803.     Type *t2 = exp->ex_ExpR->ex_Type;
  804.  
  805.     if (t1->Size == 0 && t2->Size == 0 && t1->Id != TID_ARY && t2->Id != TID_ARY) {
  806.     exp->ex_Type = &VoidType;
  807.     } else {
  808.     CompareRules(exp, 1);
  809.     exp->ex_Type = exp->ex_ExpL->ex_Type;
  810.     }
  811. }
  812.  
  813. /*
  814.  *  For CompareRules().  If we are comparing an integer quantity < sizeof(int)
  815.  *  to an integer constant and that constant fits in the quantity size, cast
  816.  *  the constant to the quantity type instead of the type to an int
  817.  */
  818.  
  819. Local  int
  820. CastIfConstantFit(pexp, type)
  821. Exp **pexp;
  822. Type *type;
  823. {
  824.     Exp *exp = *pexp;    /*  integer constant  */
  825.     short uns = exp->ex_Type->Flags & TF_UNSIGNED;
  826.  
  827.     if (uns && !(type->Flags & TF_UNSIGNED))    /*  not so simple */
  828.     return(0);
  829.  
  830.     if (uns) {
  831.     switch(type->Size) {
  832.     case 1:
  833.         if (exp->ex_Stor.st_UIntConst < 0x100) {
  834.         InsertCast(pexp, &UCharType);
  835.         return(1);
  836.         }
  837.         break;
  838.     case 2:
  839.         if (exp->ex_Stor.st_UIntConst < 0x10000) {
  840.         InsertCast(pexp, &UShortType);
  841.         return(1);
  842.         }
  843.         break;
  844.     case 4:
  845.         break;
  846.     default:
  847.         Assert(0);
  848.     }
  849.     } else {
  850.     switch(type->Size) {
  851.     case 1:
  852.         if (exp->ex_Stor.st_IntConst >= -128 && exp->ex_Stor.st_IntConst < 128) {
  853.         InsertCast(pexp, &CharType);
  854.         return(1);
  855.         }
  856.         break;
  857.     case 2:
  858.         if (exp->ex_Stor.st_IntConst >= -32768 && exp->ex_Stor.st_IntConst < 32768) {
  859.         InsertCast(pexp, &ShortType);
  860.         return(1);
  861.         }
  862.     case 4:
  863.         break;
  864.     default:
  865.         Assert(0);
  866.     }
  867.     }
  868.     return(0);
  869. }
  870.  
  871.  
  872. /*
  873.  *  Result Storage creation required?
  874.  *
  875.  *  0    yes
  876.  *  1    no, result storage already exists (even if no return storage)
  877.  *  2    no, there is no return storage
  878.  *
  879.  */
  880.  
  881. short
  882. AutoResultStorage(exp)
  883. Exp *exp;
  884. {
  885.     uword flags = exp->ex_Flags;
  886.  
  887.     if (flags & EF_COND) {
  888.     if (flags & EF_CONDACK) /*  was able to handle condition */
  889.         return(1);
  890.     }
  891.     if (flags & (EF_CRES|EF_PRES|EF_STACKACK))
  892.     return(1);
  893.     if (flags & EF_ASSEQ) {    /*  exp->ex_Stor == e1->ex_Stor */
  894.     /*
  895.      *  ass= (+=, -=, ...).  If a bit field, we allocate normal
  896.      *  storage which will be bfsto'd later
  897.      */
  898.  
  899.     if (exp->ex_ExpL->ex_Token == TokBFExt) {
  900.         Assert(exp->ex_ExpL->ex_ExpL->ex_Flags & EF_LHSASSEQ);
  901.         AllocTmpStorage(&exp->ex_Stor, exp->ex_Type, NULL);
  902.     } else {
  903.         ReuseStorage(&exp->ex_ExpL->ex_Stor, &exp->ex_Stor);
  904.     }
  905.     if (exp->ex_Flags & EF_RNU)
  906.         FreeStorage(&exp->ex_Stor);     /*  no return storage,    */
  907.     return(1);                /*    but still have result storage    */
  908.     }
  909.     if (flags & EF_RNU) {        /*    no result   */
  910.     exp->ex_Stor.st_Size = 0;   /*    make illegal    */
  911.     return(2);
  912.     }
  913.     return(0);
  914. }
  915.  
  916. /*
  917.  *  These functions return true if result storage is available.  Result
  918.  *  storage is not available when the result will not be used, but we
  919.  *  must be careful about EF_ASSEQ since ASSEQ does have result storage,
  920.  *  just no return storage to the higher level.
  921.  *
  922.  *  returns 0    <fillmeXXX>
  923.  *        1    <fillmeXXX>
  924.  *        2    temporary allocated
  925.  */
  926.  
  927. int
  928. CreateBinaryResultStorage(Exp *exp, short freeSub)
  929. {
  930.     int r = 0;
  931.  
  932.     if (freeSub) {
  933.     if (exp->ex_ExpL->ex_Stor.st_Type != ST_RegIndex)
  934.         FreeStorage(&exp->ex_ExpL->ex_Stor);
  935.     if (exp->ex_ExpR->ex_Stor.st_Type != ST_RegIndex)
  936.         FreeStorage(&exp->ex_ExpR->ex_Stor);
  937.     }
  938.  
  939.     Assert(exp->ex_Type);
  940.     switch (AutoResultStorage(exp)) {
  941.     case 0:
  942.     Assert(exp->ex_ExpR);
  943.     AllocTmpStorage(&exp->ex_Stor, exp->ex_Type, (freeSub) ? &exp->ex_ExpR->ex_Stor : NULL);
  944.     r = 2;
  945.     break;
  946.     case 1:
  947.     r = 1;
  948.     break;
  949.     }
  950.     if (freeSub) {
  951.     if (exp->ex_ExpL->ex_Stor.st_Type == ST_RegIndex)
  952.         FreeStorage(&exp->ex_ExpL->ex_Stor);
  953.     if (exp->ex_ExpR->ex_Stor.st_Type == ST_RegIndex)
  954.         FreeStorage(&exp->ex_ExpR->ex_Stor);
  955.     }
  956.     return(r);
  957. }
  958.  
  959. int
  960. CreateUnaryResultStorage(Exp *exp, short freeSub)
  961. {
  962.     if (freeSub)
  963.     FreeStorage(&exp->ex_ExpL->ex_Stor);
  964.  
  965.     Assert(exp->ex_Type);
  966.     switch (AutoResultStorage(exp)) {
  967.     case 0:
  968.     if (exp->ex_Type == &VoidType)
  969.         AllocTmpStorage(&exp->ex_Stor, exp->ex_Type, NULL);
  970.     else
  971.         AllocTmpStorage(&exp->ex_Stor, exp->ex_Type, &exp->ex_ExpL->ex_Stor);
  972.     case 1:
  973.     return(1);
  974.     }
  975.     return(0);
  976. }
  977.  
  978. int
  979. CheckConversion(exp, t1, t2)
  980. Exp *exp;
  981. Type *t1;
  982. Type *t2;
  983. {
  984.     switch(t1->Id) {
  985.     case TID_INT:
  986.     case TID_BITFIELD:
  987.     case TID_FLT:
  988.     switch(t2->Id) {
  989.     case TID_INT:
  990.     case TID_BITFIELD:
  991.     case TID_FLT:
  992.         break;
  993.     case TID_PTR:
  994.     case TID_ARY:
  995.         yerror(exp->ex_LexIdx, EWARN_INT_PTR_CONVERSION);
  996.         break;
  997.     case TID_PROC:
  998.     case TID_STRUCT:
  999.     case TID_UNION:
  1000.         yerror(exp->ex_LexIdx, EERROR_ILLEGAL_INT_CONVERSION);
  1001.         return(0);
  1002.     }
  1003.     break;
  1004.     case TID_PTR:
  1005.     case TID_ARY:
  1006.     switch(t2->Id) {
  1007.     case TID_INT:
  1008.     case TID_BITFIELD:
  1009.         yerror(exp->ex_LexIdx, EWARN_PTR_INT_CONVERSION);
  1010.         break;
  1011.     case TID_FLT:
  1012.         yerror(exp->ex_LexIdx, EERROR_ILLEGAL_PTR_CONVERSION);
  1013.         return(0);
  1014.     case TID_PTR:
  1015.     case TID_ARY:
  1016.         CheckPointerType(exp->ex_LexIdx, exp->ex_LexIdx, t1, t2);
  1017. /*        if (ProtoOnlyOpt && t1->SubType->Size != t2->SubType->Size && t1->SubType->Size && t2->SubType->Size)
  1018.         yerror(exp->ex_LexIdx, EWARN_PTR_PTR_MISMATCH); */
  1019.         break;
  1020.     case TID_PROC:
  1021.     case TID_STRUCT:
  1022.     case TID_UNION:
  1023.         yerror(exp->ex_LexIdx, EERROR_ILLEGAL_PTR_CONVERSION);
  1024.         return(0);
  1025.     }
  1026.     break;
  1027.     case TID_PROC:
  1028.     yerror(exp->ex_LexIdx, EERROR_ILLEGAL_CAST);
  1029.     break;
  1030.     case TID_STRUCT:
  1031.     case TID_UNION:
  1032.     if (t1->Size != t2->Size) {
  1033.         yerror(exp->ex_LexIdx, EERROR_ILLEGAL_STRUCT_CVT);
  1034.         return(0);
  1035.     }
  1036.     break;
  1037.     }
  1038.     return(1);
  1039. }
  1040.